package com.prp.bo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.Transaction;

import com.prp.db.DAOFactory;
import com.prp.db.HibernateSessionFactory;
import com.prp.db.idao.IUserStateDAO;
import com.prp.db.po.UserState;

public class UserStateBO {
	
	/**
	 * 用户添加状态
	 * @param content
	 * @param userId
	 * @return null if commit error
	 */
	public synchronized static UserState addState (String content, int userId) {
		Date date = new Date();
		UserState userState = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IUserStateDAO usDao = factory.getUserStateDAO();
		Transaction tx = null;
		if(content.length() > SNSConstants.MAX_STATE_SIZE)
			content = content.substring(0, SNSConstants.MAX_STATE_SIZE);
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			userState = new UserState(userId, date, content);
			usDao.save(userState);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return userState;
	}
	
	/**
	 * 用户修改状态
	 * @param content
	 * @param userId
	 * @param stateId
	 * @return null if error
	 */
	public synchronized static UserState modifyState (String content, int userId, int stateId) {
		Date date = new Date();
		UserState userState = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IUserStateDAO usDao = factory.getUserStateDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (usDao.findById(stateId) == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			userState = usDao.findById(stateId);
			if (userState.getUserId() != userId) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			if(content.length() > SNSConstants.MAX_STATE_SIZE)
				content = content.substring(0, SNSConstants.MAX_STATE_SIZE);
			userState.setState(content);
			userState.setDate(date);
			usDao.attachDirty(userState);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return userState;
	}
	
	/**
	 * 用户删除状态
	 * @param userId
	 * @param stateId
	 * @return -2 not a state of this user, -1 state not exist, 0 commit error, 1 commit OK
	 */
	public synchronized static int deleteState (int userId, int stateId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IUserStateDAO usDao = factory.getUserStateDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (usDao.findById(stateId) == null) {
				HibernateSessionFactory.getSession().close();
				return -1;
			}
			UserState userState = usDao.findById(stateId);
			if (userState.getUserId() != userId) {
				HibernateSessionFactory.getSession().close();
				return -2;
			}
			usDao.delete(userState);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 获取用户状态列表
	 * @param userId
	 * @return null if there is no state found
	 */
	public synchronized static ArrayList<UserState> getState (int userId) {
		ArrayList<UserState> result = new ArrayList<UserState>();
		DAOFactory factory = DAOFactory.getDAOFactory();
		IUserStateDAO usDao = factory.getUserStateDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			result = (ArrayList<UserState>) usDao.findByUserId(userId);
			tx.commit();
		}  catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		Collections.sort(result, new Comparator<UserState>() {

			@Override
			public int compare(UserState o1, UserState o2) {
				return o2.getDate().compareTo(o1.getDate());
			}
			
		});
		return result;
	}
	
	/**
	 * 获取用户某一状态详细
	 * @param userId
	 * @param stateId
	 * @return null if there is no such state
	 */
	public synchronized static UserState getState (int userId, int stateId) {
		UserState result = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IUserStateDAO usDao = factory.getUserStateDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (usDao.findById(stateId) == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			result = usDao.findById(stateId);
			if (result.getUserId() != userId) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			tx.commit();
		}  catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 获取用户最新状态
	 * @param userId
	 * @return null if there is no state at all
	 */
	public synchronized static UserState getLatestState (int userId) {
		UserState result = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IUserStateDAO usDao = factory.getUserStateDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArrayList<UserState> stateList = (ArrayList<UserState>) usDao.findByUserId(userId);
			if (stateList == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			Iterator<UserState> it = stateList.iterator();
			if (it.hasNext())
				result = it.next();
			else {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			while (it.hasNext()) {
				UserState tempState = it.next();
				if (tempState.getDate().compareTo(result.getDate()) > 0)
					result = tempState;
			}
			tx.commit();
		}  catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
}
